<?php
/**
 * BaseService
 * @copyright (c) 2011-2020, Hangzhou DOJI Tech Co., Ltd.
 * This is NOT a freeware, use is subject to license terms.
 * @package BsaeService.php
 * @link https://www.tingjunapp.com/
 * @author wujun@lanqb.cn
 * @: BaseService.php 310000 2020-11-06 15:13:27 $
 * */

namespace App\Services;

use App\Common\Libs\Pagination;
use App\Consts\ExceptionCode;
use App\Consts\GlobalConst;
use App\Exceptions\Error;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Validator;

class BaseService extends Service
{

    /** @var null $validator */
    public $validator = null;

    /** @var array $searchList */
    public $searchList = [
        'more' => ['have_more' => false, 'list' => []],
        'count' => ['total_count' => 0, 'page' => 1, 'page_size' => GlobalConst::BASE_PAGE_COUNT, 'list' => []],
    ];

    /**
     * @param $targetId
     * @return int
     */
    public function getTableNumber($targetId)
    {
        return sprintf('%u', crc32($targetId)) % GlobalConst::DATABASE_TABLE_NUM;
    }

    /**
     * get table with ids
     * @param $idAry
     * @param $tableName
     * @return array
     */
    public function getTableIds($idAry, $tableName)
    {
        $tabAry = [];
        foreach ($idAry as $id) {
            $num = $this->getTableNumber($id);
            $tabAry[$tableName . $num][] = $id;
        }
        return $tabAry;
    }

    /**
     * get pagination
     * @param array $paginationParams
     * @return Pagination
     */
    public function getPagination($paginationParams = [])
    {
        return (new Pagination())->getPagination($paginationParams);
    }

    /**
     * @param Builder|integer $dataProvider
     * @param $pagination
     * @param $list
     * @return array
     */
    public static function outputTotalCountList($dataProvider, $pagination, $list)
    {
        if (is_numeric($dataProvider)) {
            $count = $dataProvider;
        } else {
            $count = $dataProvider->paginate()->total();
        }
        return [
            'total_count' => $count,
            'page_size' => $pagination->pageSize,
            'page' => $pagination->page + 1,
            'list' => $list,
        ];
    }

    /**
     * @param Builder|bool $dataProvider
     * @param $pagination
     * @param $list
     * @return array
     */
    public static function outputMoreList($dataProvider, $pagination, $list)
    {
        if (is_bool($dataProvider)) {
            $haveMore = $dataProvider;
        } else {
            $pageSize = $pagination->pageSize;
            $currentPage = $dataProvider->paginate()->currentPage();
            $total = $dataProvider->paginate()->total();
            $haveMore = ($total - $currentPage * $pageSize) > 0;
        }
        return [
            'have_more' => $haveMore,
            'list' => $list,
        ];
    }

    /**
     * @param array $data
     * @param array $rule
     * @param array $message
     * @return \Illuminate\Http\JsonResponse|bool
     */
    public function validate($data = [], $rule = [], $message = [])
    {
        $this->validator = Validator::make($data, $rule, $message);
        if ($this->validator->fails()) {
            return Error::handle($this->validator->errors()->first(), ExceptionCode::ILLEGAL_PARAMETER);
        }
        return true;
    }

    /**
     * 返回错误信息
     * @param $code string|integer
     * @param string $message
     * @param string $result
     * @return \Illuminate\Http\JsonResponse
     */
    public function throwError($code = ExceptionCode::ILLEGAL_PARAMETER, $message = '', $result = '')
    {
        $message = $message ?: '';
        if (!is_int($code)) {
            $message = $code;
            $code = ExceptionCode::ILLEGAL_PARAMETER;
        }
        return Error::handle($message, $code, $result);
    }

    /**
     * 返回成功信息
     * [!] 若状态码不为200，则转到错误处理
     * @param $code
     * @param string $message
     * @param bool|mixed $data
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function operatingResult($code = true, $message = '', $data = true)
    {
        if ($code === true || $code === ExceptionCode::OPERATING_SUCCESS) {
            $code = ExceptionCode::OPERATING_SUCCESS;
            $message = $message ?: lang('Success');
            return jsonReturn($data, $code, $message);
        }
        return $this->throwError($code, $message);
    }

    /**
     * @param $data
     * @return mixed
     */
    public function listResult($data)
    {
        return $data;
    }

    /**
     * @param $data
     * @param $message
     * @return mixed
     */
    public function getResult($data, $message = '')
    {
        return $this->operatingResult(true, $message, $data);
    }

}
